// cesium交互类封装
import * as Cesium from 'cesium/Cesium'
import store from "@/store";

class CesiumMethods {
  constructor(viewer) {
    this.viewer = viewer;
    this.routePoint = undefined
    this.routePolyline = undefined
    // 去除Cesium品牌标识
    this.viewer.cesiumWidget.creditContainer.style.display = "none";
  }


  /**
   * 显示比例尺、罗盘和缩放组件
   */
  // showNavigation(){
  //   this.viewer.extend(Cesium.viewerCesiumNavigationMixin, {
  //     enableCompass: true,
  //     //罗盘组件true启用，false禁用，默认值为true。
  //     enableZoomControls: true,
  //     //缩放组件true启用，false禁用，默认值为true。
  //     enableDistanceLegend: true,
  //     //比例尺组件true启用，false禁用，默认值为true。
  //     enableCompassOuterRing: true,
  //     //指南针外环组件true启用，false禁用，默认值为true。
  //   });
  // }

  lookAt(lon,lat,h=10){
    let target = new Cesium.Cartesian3.fromDegrees(lon,lat,h)
    var heading = Cesium.Math.toRadians(0.0);
    var pitch = Cesium.Math.toRadians(-60.0);
    var range = 5000.0;
    var i = 0;
    this.viewer.camera.lookAt(target, new Cesium.HeadingPitchRange(heading, pitch,range));
  }
  flyTo(home) {
    this.viewer.camera.flyTo({
      // Cesium的坐标是以地心为原点，一向指向南美洲，一向指向亚洲，一向指向北极州
      // fromDegrees()方法，将经纬度和高程转换为世界坐标
      duration: 2, // 时间，秒
      destination: home,
      orientation: {
        // 指向
        heading: Cesium.Math.toRadians(0),
        // 视角
        pitch: Cesium.Math.toRadians(-90),
        roll: 0.0,
      },
    });
  }

  addGeoserverLayer(baseurl,workspace,layername){
    let wmsprovider = new Cesium.WebMapServiceImageryProvider({
      url: baseurl + workspace + '/wms',
      enablePickFeatures: true,
      defaultAlpha: 0,
      layers: layername,
      parameters: {
        service: 'WMS',
        version: '1.1.1',
        request: 'GetMap',
        format: 'image/png8',
        styles: '',
        transparent: true
      }
    });
    let imagelayer = new Cesium.ImageryLayer(wmsprovider);
    this.viewer.imageryLayers.add(imagelayer);

  }

  // 在地图中添加三维模型
  placeModelAt(coords, id, callback) {
    // this.viewer.entities.removeAll();
    const position = Cesium.Cartesian3.fromDegrees(
        coords[0], // 经度
        coords[1], // 纬度
        2.0 // 高度
    );
    const heading = Cesium.Math.toRadians(135);
    const pitch = 0;
    const roll = 0;
    const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);

    let siteEntity = new Cesium.Entity({
      id: "location-" + id,
      name: "location_" + id,
      position: position,
      orientation: Cesium.Transforms.headingPitchRollQuaternion(position, hpr),
      model: {
        uri: "../Assets/Wood_Tower.glb",
        heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        minimumPixelSize: 40,
        maximumScale: 256,
        color: Cesium.Color.fromAlpha(Cesium.Color.YELLOW, 1),
        colorBlendMode: Cesium.ColorBlendMode.MIX,
        silhouetteColor: Cesium.Color.YELLOW,
        silhouetteSize: 5,
      },
    });
    this.viewer.entities.add(siteEntity);
    callback(siteEntity);
  }

  addPng(response, name) {
    let pngpath = pngurl + "?airportName=" + name;
    let x = Math.PI / 180; // 1° = x 弧度
    let west = response.extent.west * x;
    let south = response.extent.south * x;
    let east = response.extent.east * x;
    let north = response.extent.north * x;
    let rec = new Cesium.Rectangle(west, south, east, north);
    let pngEntity;
    if (response.skyH === -1) {
      pngEntity = this.getPngRectangle(pngpath, rec, undefined);
    } else {
      pngEntity = this.getPngRectangle(pngpath, rec, Number(response.skyH));
    }
    this.viewer.entities.add(pngEntity);
    this.viewer.flyTo(pngEntity, {
      duration: 2,
    });
  }

  // 根据id移除地图中的站点，只移除第一个匹配者
  removeSiteinMapbyID(id) {
    let en = this.viewer.entities.getById("site-" + id);
    this.viewer.entities.removeById("site-" + id);
  }

  // Cartesian3坐标转为WGS84坐标（角度经纬度）
  Cartesian3ToWGS84(Cartesian3) {
    const cartographicPosition =
        Cesium.Ellipsoid.WGS84.cartesianToCartographic(Cartesian3);
    var lat = cartographicPosition.latitude * (180 / Math.PI); //弧度转为角度
    var lon = cartographicPosition.longitude * (180 / Math.PI);
    return {lon: lon, lat: lat, height: cartographicPosition.height};
  }

  // 相机聚焦于当前地图中的实体 Entities
  focusonEntities() {
    this.viewer.flyTo(this.viewer.entities, {
      duration: 2,
      orientation: {
        // 指向
        heading: Cesium.Math.toRadians(0),
        // 视角
        pitch: Cesium.Math.toRadians(-60),
        roll: 0.0,
      },
    });
  }

  flyToLatlng(lon, lat) {
    // 移动视图
    this.viewer.camera.flyTo({
      duration: 2, // 时间，秒
      destination: Cesium.Cartesian3.fromDegrees(
          Number(lon),
          Number(lat),
          8000.0
      ),
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-90),
        roll: 0.0,
      },
    });
  }

  // 鼠标移动显示经纬度控件
  mouseMoveLocInfo() {
    const _viewer = this.viewer
    var _positionDiv = document.createElement("div")
    _positionDiv.style.cssText = `
      position: fixed;
      bottom: 4px;
      right: 200px;
      width: 380px;
      background-color: rgba(47,53,60,.8);
      color: #fff;
      font-size: 15px;
      text-align: center;
      z-index: 100;
      padding: 5px;
      border-radius: 3px;
    `;
    var canvas = _viewer.scene.canvas;
    //具体事件的实现
    var ellipsoid = _viewer.scene.globe.ellipsoid;
    var handler = new Cesium.ScreenSpaceEventHandler(canvas);
    _viewer.container.append(_positionDiv)
    handler.setInputAction(function (movement) {
      //捕获椭球体，将笛卡尔二维平面坐标转为椭球体的笛卡尔三维坐标，返回球体表面的点
      var cartesian = _viewer.camera.pickEllipsoid(
          movement.endPosition,
          ellipsoid
      );
      if (cartesian) {
        //将笛卡尔三维坐标转为地图坐标（弧度）
        var cartographic = _viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
        //将地图坐标（弧度）转为十进制的度数
        var lat_String = Cesium.Math.toDegrees(cartographic.latitude).toFixed(4); // 纬度
        var log_String = Cesium.Math.toDegrees(cartographic.longitude).toFixed(4); // 经度
        // var alti_String = (_viewer.camera.positionCartographic.alt / 1000).toFixed(2); // 视高
        var elec_String = _viewer.scene.globe.getHeight(cartographic).toFixed(2); // 海拔

        _positionDiv.innerHTML = `经度：${log_String} , 纬度：${lat_String} , 海拔：${elec_String} m`;
        // _positionDiv.innerHTML = `经度：${log_String} 纬度：${lat_String} 视高：${alti_String} 海拔：${elec_String}`;
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  }

  // 在地图中画一条连接p1-p2的贴地线
  surfaceLine(p1, p2) {
    // 定义一条线
    var LineEntity = new Cesium.Entity({
      name: "Terrain Line",
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray([
          p1[0], p1[1],
          p2[0], p2[1]
        ]),
        width: 10,
        material: Cesium.Color.YELLOW,
        clampToGround: true
      }
    });
    this.viewer.entities.add(LineEntity);
    this.viewer.flyTo(LineEntity)
  }
  // 在地图中画一条连接发射机-接收机的非贴地线
  // drawLine(Transmitterp2p, Receiverp2p) {
  //   var terrainP = Cesium.createWorldTerrain();
  //   var positions = [Cesium.Cartographic.fromDegrees(Transmitterp2p.lng, Transmitterp2p.lat),
  //     Cesium.Cartographic.fromDegrees(Receiverp2p.lng, Receiverp2p.lat)]
  //   var promise = Cesium.sampleTerrain(terrainP, 12, positions);
  //   Cesium.when(promise, function (uppositions) {
  //     // 定义一条线
  //     let LineEntity = new Cesium.Entity({
  //       airportName: "Terrain Line",
  //       polyline: {
  //         positions: [Cesium.Cartesian3.fromDegrees(positions[0].lng, positions[0].lat, positions[0].alt + Transmitterp2p.alt),
  //           Cesium.Cartesian3.fromDegrees(positions[1].lng, positions[1].lat, positions[1].alt + Receiverp2p.alt)],
  //         width: 10,
  //         material: Cesium.Color.YELLOW,
  //         clampToGround: false
  //       }
  //     });
  //     this.viewer.entities.add(LineEntity);
  //     this.viewer.flyTo(LineEntity)
  //   });
  //
  // }

  /**
   * 添加航线，在地图中绘制线要素和点要素，并将视角正对该要素
   * @param listPionts 绘制线要素的点集合，WGS84坐标系，每个点应具有lng、lat、alt属性
   */
  addAirline(listPionts) {
    // 创建点
    this.routePoint = this.viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection())
    // 创建线
    // const lineDataSource = this.viewer.scene.primitives.add(new Cesium.PolylineCollection())
    let pts = []
    for (const i in listPionts) { // for in 遍历对象属性，array的属性是下标，所以p=0,1,2,...,length
      pts.push(Cesium.Cartesian3.fromDegrees(Number(listPionts[i].lng),Number(listPionts[i].lat),0))
      this.routePoint.add({
        pixelSize: 10,
        color: Cesium.Color.YELLOW,
        position: Cesium.Cartesian3.fromDegrees(Number(listPionts[i].lng),Number(listPionts[i].lat),0)
      });
    }
    this.routePolyline = new Cesium.Entity({
      polyline: {
        positions: pts,
        width: 4,
        material: Cesium.Color.YELLOW,
        clampToGround: true
      }
    })
    this.viewer.entities.add(this.routePolyline)
    this.viewer.flyTo(this.routePolyline,{duration:2})
  }

  /**
   * 移除地图中全部实体元素，包括primitive和Entity
   */
  removeAllElemts(){
    this.viewer.entities.remove(this.routePolyline)
    // console.dir(this.viewer.scene.primitives)
    this.viewer.scene.primitives.remove(this.routePoint)
    this.viewer.entities.removeAll()
  }

  /**
   * 在指定位置添加定位图标，并zoomAt
   * @param lng 十进制经度
   * @param lat 十进制纬度
   */
  locate(lng,lat){
    const czml = [{
      id: "document",
      name: '机场位置',
      version: '1.0',
      },
      {
        id: "red",
        name: "机场位置",
        position: {
          cartographicDegrees: [lng, lat, 10.0],
        },
        point: {
          color: {
            rgba: [255, 255, 255, 255],
          },
          outlineColor: {
            rgba: [255, 0, 0, 255],
          },
          outlineWidth: 4,
          pixelSize: 10,
        },
      }]
    const dataSourcePromise = Cesium.CzmlDataSource.load(czml);
    this.viewer.dataSources.add(dataSourcePromise).then(
        r => {
          this.viewer.zoomTo(dataSourcePromise, new Cesium.HeadingPitchRange (0, -Math.PI/2, 8000))
        });
  }

  /**
   * 在指定位置添加定位图标Entity，并zoomAt
   * @param lng 十进制经度
   * @param lat 十进制纬度
   */
  locateEntity(lng,lat,str){
    let entity = new  Cesium.Entity({
      name:'机场',
      position: Cesium.Cartesian3.fromDegrees(lng,lat,10),
      point: {
        show: true,
        pixelSize: 10,
        color: Cesium.Color.RED,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 3,
      },
      label:{
        text: str,
        font: "40px sans-serif",
        fillColor: Cesium.Color.WHITE,
        style: Cesium.LabelStyle.FILL,
        pixelOffset: new Cesium.Cartesian2(20, -10),
        eyeOffset: new Cesium.Cartesian3(0, 0, -10),
        horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        scale: 0.5,
        showBackground: true,
        backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8),
        backgroundPadding: new Cesium.Cartesian2(10, 10),
      },
    });
    this.viewer.entities.add(entity)
    this.viewer.zoomTo(entity, new Cesium.HeadingPitchRange (0, -Math.PI/2, 8000))
  }
}

export default CesiumMethods;
